home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / getchar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-28  |  61.6 KB  |  2,680 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * getchar.c
  11.  *
  12.  * functions related with getting a character from the user/mapping/redo/...
  13.  *
  14.  * manipulations with redo buffer and stuff buffer
  15.  * mappings and abbreviations
  16.  */
  17.  
  18. #include "vim.h"
  19.  
  20. /*
  21.  * structure used to store one block of the stuff/redo/macro buffers
  22.  */
  23. struct bufblock
  24. {
  25.     struct bufblock *b_next;    /* pointer to next bufblock */
  26.     char_u        b_str[1];    /* contents (actually longer) */
  27. };
  28.  
  29. #define MINIMAL_SIZE 20            /* minimal size for b_str */
  30.  
  31. /*
  32.  * header used for the stuff buffer and the redo buffer
  33.  */
  34. struct buffheader
  35. {
  36.     struct bufblock bh_first;    /* first (dummy) block of list */
  37.     struct bufblock *bh_curr;    /* bufblock for appending */
  38.     int        bh_index;    /* index for reading */
  39.     int        bh_space;    /* space in bh_curr for appending */
  40. };
  41.  
  42. static struct buffheader stuffbuff = {{NULL, {NUL}}, NULL, 0, 0};
  43. static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
  44. static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
  45. static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
  46. static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
  47. static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
  48.  
  49. /*
  50.  * when block_redo is TRUE redo buffer will not be changed
  51.  * used by edit() to repeat insertions and 'V' command for redoing
  52.  */
  53. static int    block_redo = FALSE;
  54.  
  55. /*
  56.  * structure used for mapping
  57.  */
  58. struct mapblock
  59. {
  60.     struct mapblock *m_next;        /* next mapblock in list */
  61.     char_u        *m_keys;        /* mapped from */
  62.     int             m_keylen;        /* strlen(m_keys) */
  63.     char_u        *m_str;        /* mapped to */
  64.     int             m_mode;        /* valid mode */
  65.     int             m_noremap;        /* if non-zero no re-mapping for m_str */
  66. };
  67.  
  68. /*
  69.  * Make a hash value for a mapping.
  70.  * "mode" is the lower 4 bits of the State for the mapping.
  71.  * "c1" is the first character of the "lhs".
  72.  * Returns a value between 0 and 255, index in maphash.
  73.  * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
  74.  */
  75. #define MAP_HASH(mode, c1) (((mode) & (NORMAL + VISUAL + OP_PENDING)) ? (c1) : ((c1) ^ 0x80))
  76.  
  77. /*
  78.  * Each mapping is put in one of the 256 hash lists, to speed up finding it.
  79.  */
  80. static struct mapblock    *(maphash[256]);
  81. static int        maphash_valid = FALSE;
  82.  
  83. /*
  84.  * List used for abbreviations.
  85.  */
  86. static struct mapblock *first_abbr = NULL; /* first entry in abbrlist */
  87.  
  88. /*
  89.  * variables used by vgetorpeek() and flush_buffers()
  90.  *
  91.  * typebuf[] contains all characters that are not consumed yet.
  92.  * typebuf[typeoff] is the first valid character in typebuf[].
  93.  * typebuf[typeoff + typelen - 1] is the last valid char.
  94.  * typebuf[typeoff + typelen] must be NUL.
  95.  * The part in front may contain the result of mappings, abbreviations and
  96.  * @a commands. The length of this part is typemaplen.
  97.  * After it are characters that come from the terminal.
  98.  * no_abbr_cnt is the number of characters in typebuf that should not be
  99.  * considered for abbreviations.
  100.  * Some parts of typebuf may not be mapped. These parts are remembered in
  101.  * noremapbuf, which is the same length as typebuf and contains TRUE for the
  102.  * characters that are not to be remapped. noremapbuf[typeoff] is the first
  103.  * valid flag.
  104.  * (typebuf has been put in globals.h, because check_termcode() needs it).
  105.  */
  106. static char_u    *noremapbuf = NULL;      /* flags for typeahead characters */
  107. /* typebuf has three parts: room in front (for result of mappings), the middle
  108.  * for typeahead and room for new characters (which needs to be 3 * MAXMAPLEN)
  109.  * for the Amiga).
  110.  */
  111. #define TYPELEN_INIT    (5 * (MAXMAPLEN + 3))
  112. static char_u    typebuf_init[TYPELEN_INIT];        /* initial typebuf */
  113. static char_u    noremapbuf_init[TYPELEN_INIT];        /* initial noremapbuf */
  114.  
  115. static int    typemaplen = 0;        /* nr of mapped characters in typebuf */
  116. static int    no_abbr_cnt = 0;    /* nr of chars without abbrev. in typebuf */
  117. static int    last_recorded_len = 0;    /* number of last recorded chars */
  118.  
  119. static void    free_buff __ARGS((struct buffheader *));
  120. static char_u    *get_bufcont __ARGS((struct buffheader *, int));
  121. static void    add_buff __ARGS((struct buffheader *, char_u *));
  122. static void    add_num_buff __ARGS((struct buffheader *, long));
  123. static void    add_char_buff __ARGS((struct buffheader *, int));
  124. static int    read_stuff __ARGS((int));
  125. static void    start_stuff __ARGS((void));
  126. static int    read_redo __ARGS((int, int));
  127. static void    copy_redo __ARGS((int));
  128. static void    init_typebuf __ARGS((void));
  129. static void    gotchars __ARGS((char_u *, int));
  130. static void    may_sync_undo __ARGS((void));
  131. static void    closescript __ARGS((void));
  132. static int    vgetorpeek __ARGS((int));
  133. static void    map_free __ARGS((struct mapblock **));
  134. static void    validate_maphash __ARGS((void));
  135. static void    showmap __ARGS((struct mapblock *));
  136.  
  137. /*
  138.  * free and clear a buffer
  139.  */
  140.     static void
  141. free_buff(buf)
  142.     struct buffheader *buf;
  143. {
  144.     struct bufblock        *p, *np;
  145.  
  146.     for (p = buf->bh_first.b_next; p != NULL; p = np)
  147.     {
  148.         np = p->b_next;
  149.         vim_free(p);
  150.     }
  151.     buf->bh_first.b_next = NULL;
  152. }
  153.  
  154. /*
  155.  * return the contents of a buffer as a single string
  156.  */
  157.     static char_u *
  158. get_bufcont(buffer, dozero)
  159.     struct buffheader    *buffer;
  160.     int            dozero;        /* count == zero is not an error */
  161. {
  162.     long_u        count = 0;
  163.     char_u        *p = NULL;
  164.     char_u        *p2;
  165.     char_u        *str;
  166.     struct bufblock *bp;
  167.  
  168. /* compute the total length of the string */
  169.     for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
  170.     count += STRLEN(bp->b_str);
  171.  
  172.     if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL)
  173.     {
  174.     p2 = p;
  175.     for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
  176.         for (str = bp->b_str; *str; )
  177.         *p2++ = *str++;
  178.     *p2 = NUL;
  179.     }
  180.     return (p);
  181. }
  182.  
  183. /*
  184.  * return the contents of the record buffer as a single string
  185.  *  and clear the record buffer
  186.  */
  187.     char_u *
  188. get_recorded()
  189. {
  190.     char_u *p;
  191.     size_t  len;
  192.  
  193.     p = get_bufcont(&recordbuff, TRUE);
  194.     free_buff(&recordbuff);
  195.     /*
  196.      * Remove the characters that were added the last time, these must be the
  197.      * (possibly mapped) characters that stopped recording.
  198.      */
  199.     len = STRLEN(p);
  200.     if ((int)len >= last_recorded_len)
  201.     p[len - last_recorded_len] = NUL;
  202.     return (p);
  203. }
  204.  
  205. /*
  206.  * return the contents of the redo buffer as a single string
  207.  */
  208.     char_u *
  209. get_inserted()
  210. {
  211.     return(get_bufcont(&redobuff, FALSE));
  212. }
  213.  
  214. /*
  215.  * add string "s" after the current block of buffer "buf"
  216.  */
  217.     static void
  218. add_buff(buf, s)
  219.     struct buffheader    *buf;
  220.     char_u        *s;
  221. {
  222.     struct bufblock *p;
  223.     long_u        n;
  224.     long_u        len;
  225.  
  226.     if ((n = STRLEN(s)) == 0)            /* don't add empty strings */
  227.     return;
  228.  
  229.     if (buf->bh_first.b_next == NULL)        /* first add to list */
  230.     {
  231.     buf->bh_space = 0;
  232.     buf->bh_curr = &(buf->bh_first);
  233.     }
  234.     else if (buf->bh_curr == NULL)        /* buffer has already been read */
  235.     {
  236.     EMSG("Add to read buffer");
  237.     return;
  238.     }
  239.     else if (buf->bh_index != 0)
  240.     STRCPY(buf->bh_first.b_next->b_str,
  241.                  buf->bh_first.b_next->b_str + buf->bh_index);
  242.     buf->bh_index = 0;
  243.  
  244.     if (buf->bh_space >= (int)n)
  245.     {
  246.     strcat((char *)buf->bh_curr->b_str, (char *)s);
  247.     buf->bh_space -= n;
  248.     }
  249.     else
  250.     {
  251.     if (n < MINIMAL_SIZE)
  252.         len = MINIMAL_SIZE;
  253.     else
  254.         len = n;
  255.     p = (struct bufblock *)lalloc((long_u)(sizeof(struct bufblock) + len),
  256.                                     TRUE);
  257.     if (p == NULL)
  258.         return; /* no space, just forget it */
  259.     buf->bh_space = len - n;
  260.     STRCPY(p->b_str, s);
  261.  
  262.     p->b_next = buf->bh_curr->b_next;
  263.     buf->bh_curr->b_next = p;
  264.     buf->bh_curr = p;
  265.     }
  266.     return;
  267. }
  268.  
  269.     static void
  270. add_num_buff(buf, n)
  271.     struct buffheader *buf;
  272.     long          n;
  273. {
  274.     char_u    number[32];
  275.  
  276.     sprintf((char *)number, "%ld", n);
  277.     add_buff(buf, number);
  278. }
  279.  
  280.     static void
  281. add_char_buff(buf, c)
  282.     struct buffheader *buf;
  283.     int              c;
  284. {
  285.     char_u  temp[4];
  286.  
  287.     /*
  288.      * translate special key code into three byte sequence
  289.      */
  290.     if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL)
  291.     {
  292.     temp[0] = K_SPECIAL;
  293.     temp[1] = K_SECOND(c);
  294.     temp[2] = K_THIRD(c);
  295.     temp[3] = NUL;
  296.     }
  297.     else
  298.     {
  299.     temp[0] = c;
  300.     temp[1] = NUL;
  301.     }
  302.     add_buff(buf, temp);
  303. }
  304.  
  305. /*
  306.  * get one character from the stuff buffer
  307.  * If advance == TRUE go to the next char.
  308.  */
  309.     static int
  310. read_stuff(advance)
  311.     int        advance;
  312. {
  313.     char_u        c;
  314.     struct bufblock    *curr;
  315.  
  316.  
  317.     if (stuffbuff.bh_first.b_next == NULL)  /* buffer is empty */
  318.     return NUL;
  319.  
  320.     curr = stuffbuff.bh_first.b_next;
  321.     c = curr->b_str[stuffbuff.bh_index];
  322.  
  323.     if (advance)
  324.     {
  325.     if (curr->b_str[++stuffbuff.bh_index] == NUL)
  326.     {
  327.         stuffbuff.bh_first.b_next = curr->b_next;
  328.         vim_free(curr);
  329.         stuffbuff.bh_index = 0;
  330.     }
  331.     }
  332.     return c;
  333. }
  334.  
  335. /*
  336.  * prepare stuff buffer for reading (if it contains something)
  337.  */
  338.     static void
  339. start_stuff()
  340. {
  341.     if (stuffbuff.bh_first.b_next != NULL)
  342.     {
  343.     stuffbuff.bh_curr = &(stuffbuff.bh_first);
  344.     stuffbuff.bh_space = 0;
  345.     }
  346. }
  347.  
  348. /*
  349.  * check if the stuff buffer is empty
  350.  */
  351.     int
  352. stuff_empty()
  353. {
  354.     return (stuffbuff.bh_first.b_next == NULL);
  355. }
  356.  
  357. /*
  358.  * Remove the contents of the stuff buffer and the mapped characters in the
  359.  * typeahead buffer (used in case of an error). If 'typeahead' is true,
  360.  * flush all typeahead characters (used when interrupted by a CTRL-C).
  361.  */
  362.     void
  363. flush_buffers(typeahead)
  364.     int typeahead;
  365. {
  366.     init_typebuf();
  367.  
  368.     start_stuff();
  369.     while (read_stuff(TRUE) != NUL)
  370.     ;
  371.  
  372.     if (typeahead)        /* remove all typeahead */
  373.     {
  374.     /*
  375.      * We have to get all characters, because we may delete the first part
  376.      * of an escape sequence.
  377.      * In an xterm we get one char at a time and we have to get them all.
  378.      */
  379.     while (inchar(typebuf, typebuflen - 1, 10L))
  380.         ;
  381.     typeoff = MAXMAPLEN;
  382.     typelen = 0;
  383.     }
  384.     else            /* remove mapped characters only */
  385.     {
  386.     typeoff += typemaplen;
  387.     typelen -= typemaplen;
  388.     }
  389.     typemaplen = 0;
  390.     no_abbr_cnt = 0;
  391. }
  392.  
  393. /*
  394.  * The previous contents of the redo buffer is kept in old_redobuffer.
  395.  * This is used for the CTRL-O <.> command in insert mode.
  396.  */
  397.     void
  398. ResetRedobuff()
  399. {
  400.     if (!block_redo)
  401.     {
  402.     free_buff(&old_redobuff);
  403.     old_redobuff = redobuff;
  404.     redobuff.bh_first.b_next = NULL;
  405.     }
  406. }
  407.  
  408. /*
  409.  * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
  410.  * Used before executing autocommands.
  411.  */
  412.     void
  413. saveRedobuff()
  414. {
  415.     save_redobuff = redobuff;
  416.     redobuff.bh_first.b_next = NULL;
  417.     save_old_redobuff = old_redobuff;
  418.     old_redobuff.bh_first.b_next = NULL;
  419. }
  420.  
  421. /*
  422.  * Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
  423.  * Used after executing autocommands.
  424.  */
  425.     void
  426. restoreRedobuff()
  427. {
  428.     free_buff(&redobuff);
  429.     redobuff = save_redobuff;
  430.     free_buff(&old_redobuff);
  431.     old_redobuff = save_old_redobuff;
  432. }
  433.  
  434.     void
  435. AppendToRedobuff(s)
  436.     char_u       *s;
  437. {
  438.     if (!block_redo)
  439.     add_buff(&redobuff, s);
  440. }
  441.  
  442.     void
  443. AppendCharToRedobuff(c)
  444.     int           c;
  445. {
  446.     if (!block_redo)
  447.     add_char_buff(&redobuff, c);
  448. }
  449.  
  450.     void
  451. AppendNumberToRedobuff(n)
  452.     long        n;
  453. {
  454.     if (!block_redo)
  455.     add_num_buff(&redobuff, n);
  456. }
  457.  
  458.     void
  459. stuffReadbuff(s)
  460.     char_u       *s;
  461. {
  462.     add_buff(&stuffbuff, s);
  463. }
  464.  
  465.     void
  466. stuffcharReadbuff(c)
  467.     int           c;
  468. {
  469.     add_char_buff(&stuffbuff, c);
  470. }
  471.  
  472.     void
  473. stuffnumReadbuff(n)
  474.     long    n;
  475. {
  476.     add_num_buff(&stuffbuff, n);
  477. }
  478.  
  479. /*
  480.  * Read a character from the redo buffer.
  481.  * The redo buffer is left as it is.
  482.  * if init is TRUE, prepare for redo, return FAIL if nothing to redo, OK
  483.  * otherwise
  484.  * if old is TRUE, use old_redobuff instead of redobuff
  485.  */
  486.     static int
  487. read_redo(init, old_redo)
  488.     int        init;
  489.     int        old_redo;
  490. {
  491.     static struct bufblock  *bp;
  492.     static char_u        *p;
  493.     int                c;
  494.  
  495.     if (init)
  496.     {
  497.     if (old_redo)
  498.         bp = old_redobuff.bh_first.b_next;
  499.     else
  500.         bp = redobuff.bh_first.b_next;
  501.     if (bp == NULL)
  502.         return FAIL;
  503.     p = bp->b_str;
  504.     return OK;
  505.     }
  506.     if ((c = *p) != NUL)
  507.     {
  508.     if (c == K_SPECIAL)
  509.     {
  510.         c = TO_SPECIAL(p[1], p[2]);
  511.         p += 2;
  512.     }
  513.     if (*++p == NUL && bp->b_next != NULL)
  514.     {
  515.         bp = bp->b_next;
  516.         p = bp->b_str;
  517.     }
  518.     }
  519.     return c;
  520. }
  521.  
  522. /*
  523.  * copy the rest of the redo buffer into the stuff buffer (could be done faster)
  524.  * if old_redo is TRUE, use old_redobuff instead of redobuff
  525.  */
  526.     static void
  527. copy_redo(old_redo)
  528.     int        old_redo;
  529. {
  530.     int        c;
  531.  
  532.     while ((c = read_redo(FALSE, old_redo)) != NUL)
  533.     stuffcharReadbuff(c);
  534. }
  535.  
  536. /*
  537.  * Stuff the redo buffer into the stuffbuff.
  538.  * Insert the redo count into the command.
  539.  * If 'old_redo' is TRUE, the last but one command is repeated
  540.  * instead of the last command (inserting text). This is used for
  541.  * CTRL-O <.> in insert mode
  542.  *
  543.  * return FAIL for failure, OK otherwise
  544.  */
  545.     int
  546. start_redo(count, old_redo)
  547.     long    count;
  548.     int        old_redo;
  549. {
  550.     int        c;
  551.  
  552.     /* init the pointers; return if nothing to redo */
  553.     if (read_redo(TRUE, old_redo) == FAIL)
  554.     return FAIL;
  555.  
  556.     c = read_redo(FALSE, old_redo);
  557.  
  558.     /* copy the buffer name, if present */
  559.     if (c == '"')
  560.     {
  561.     add_buff(&stuffbuff, (char_u *)"\"");
  562.     c = read_redo(FALSE, old_redo);
  563.  
  564.     /* if a numbered buffer is used, increment the number */
  565.     if (c >= '1' && c < '9')
  566.         ++c;
  567.     add_char_buff(&stuffbuff, c);
  568.     c = read_redo(FALSE, old_redo);
  569.     }
  570.  
  571.     if (c == 'v')   /* redo Visual */
  572.     {
  573.     VIsual = curwin->w_cursor;
  574.     VIsual_active = TRUE;
  575.     redo_VIsual_busy = TRUE;
  576.     c = read_redo(FALSE, old_redo);
  577.     }
  578.  
  579.     /* try to enter the count (in place of a previous count) */
  580.     if (count)
  581.     {
  582.     while (isdigit(c))    /* skip "old" count */
  583.         c = read_redo(FALSE, old_redo);
  584.     add_num_buff(&stuffbuff, count);
  585.     }
  586.  
  587.     /* copy from the redo buffer into the stuff buffer */
  588.     add_char_buff(&stuffbuff, c);
  589.     copy_redo(old_redo);
  590.     return OK;
  591. }
  592.  
  593. /*
  594.  * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
  595.  * the redo buffer into the stuffbuff.
  596.  * return FAIL for failure, OK otherwise
  597.  */
  598.     int
  599. start_redo_ins()
  600. {
  601.     int        c;
  602.  
  603.     if (read_redo(TRUE, FALSE) == FAIL)
  604.     return FAIL;
  605.     start_stuff();
  606.  
  607. /* skip the count and the command character */
  608.     while ((c = read_redo(FALSE, FALSE)) != NUL)
  609.     {
  610.     if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL)
  611.     {
  612.         if (c == 'O' || c == 'o')
  613.         stuffReadbuff(NL_STR);
  614.         break;
  615.     }
  616.     }
  617.  
  618. /* copy the typed text from the redo buffer into the stuff buffer */
  619.     copy_redo(FALSE);
  620.     block_redo = TRUE;
  621.     return OK;
  622. }
  623.  
  624.     void
  625. set_redo_ins()
  626. {
  627.     block_redo = TRUE;
  628. }
  629.  
  630.     void
  631. stop_redo_ins()
  632. {
  633.     block_redo = FALSE;
  634. }
  635.  
  636. /*
  637.  * Initialize typebuf to point to typebuf_init.
  638.  * Alloc() cannot be used here: In out-of-memory situations it would
  639.  * be impossible to type anything.
  640.  */
  641.     static void
  642. init_typebuf()
  643. {
  644.     if (typebuf == NULL)
  645.     {
  646.     typebuf = typebuf_init;
  647.     noremapbuf = noremapbuf_init;
  648.     typebuflen = TYPELEN_INIT;
  649.     typelen = 0;
  650.     typeoff = 0;
  651.     }
  652. }
  653.  
  654. /*
  655.  * insert a string in position 'offset' in the typeahead buffer (for "@r"
  656.  * and ":normal" command, vgetorpeek() and check_termcode())
  657.  *
  658.  * If noremap is 0, new string can be mapped again.
  659.  * If noremap is -1, new string cannot be mapped again.
  660.  * If noremap is >0, that many characters of the new string cannot be mapped.
  661.  *
  662.  * If nottyped is TRUE, the string does not return KeyTyped (don't use when
  663.  * offset is non-zero!).
  664.  *
  665.  * return FAIL for failure, OK otherwise
  666.  */
  667.     int
  668. ins_typebuf(str, noremap, offset, nottyped)
  669.     char_u  *str;
  670.     int        noremap;
  671.     int        offset;
  672.     int        nottyped;
  673. {
  674.     char_u  *s1, *s2;
  675.     int        newlen;
  676.     int        addlen;
  677.     int        i;
  678.     int        newoff;
  679.  
  680.     init_typebuf();
  681.  
  682.     addlen = STRLEN(str);
  683.     /*
  684.      * Easy case: there is room in front of typebuf[typeoff]
  685.      */
  686.     if (offset == 0 && addlen <= typeoff)
  687.     {
  688.     typeoff -= addlen;
  689.     vim_memmove(typebuf + typeoff, str, (size_t)addlen);
  690.     }
  691.     /*
  692.      * Need to allocate new buffer.
  693.      * In typebuf there must always be room for 3 * MAXMAPLEN + 4 characters.
  694.      * We add some extra room to avoid having to allocate too often.
  695.      */
  696.     else
  697.     {
  698.     newoff = MAXMAPLEN + 4;
  699.     newlen = typelen + addlen + newoff + 4 * (MAXMAPLEN + 4);
  700.     if (newlen < 0)            /* string is getting too long */
  701.     {
  702.         emsg(e_toocompl);        /* also calls flush_buffers */
  703.         setcursor();
  704.         return FAIL;
  705.     }
  706.     s1 = alloc(newlen);
  707.     if (s1 == NULL)            /* out of memory */
  708.         return FAIL;
  709.     s2 = alloc(newlen);
  710.     if (s2 == NULL)            /* out of memory */
  711.     {
  712.         vim_free(s1);
  713.         return FAIL;
  714.     }
  715.     typebuflen = newlen;
  716.  
  717.     /* copy the old chars, before the insertion point */
  718.     vim_memmove(s1 + newoff, typebuf + typeoff, (size_t)offset);
  719.     /* copy the new chars */
  720.     vim_memmove(s1 + newoff + offset, str, (size_t)addlen);
  721.     /* copy the old chars, after the insertion point, including the    NUL at
  722.      * the end */
  723.     vim_memmove(s1 + newoff + offset + addlen, typebuf + typeoff + offset,
  724.                           (size_t)(typelen - offset + 1));
  725.     if (typebuf != typebuf_init)
  726.         vim_free(typebuf);
  727.     typebuf = s1;
  728.  
  729.     vim_memmove(s2 + newoff, noremapbuf + typeoff, (size_t)offset);
  730.     vim_memmove(s2 + newoff + offset + addlen,
  731.            noremapbuf + typeoff + offset, (size_t)(typelen - offset));
  732.     if (noremapbuf != noremapbuf_init)
  733.         vim_free(noremapbuf);
  734.     noremapbuf = s2;
  735.  
  736.     typeoff = newoff;
  737.     }
  738.     typelen += addlen;
  739.  
  740.     /*
  741.      * Adjust noremapbuf[] for the new characters:
  742.      * If noremap  < 0: all the new characters are flagged not remappable
  743.      * If noremap == 0: all the new characters are flagged mappable
  744.      * If noremap  > 0: 'noremap' characters are flagged not remappable, the
  745.      *            rest mappable
  746.      */
  747.     if (noremap < 0)        /* length not specified */
  748.     noremap = addlen;
  749.     for (i = 0; i < addlen; ++i)
  750.     noremapbuf[typeoff + i + offset] = (noremap-- > 0);
  751.  
  752.             /* this is only correct for offset == 0! */
  753.     if (nottyped)            /* the inserted string is not typed */
  754.     typemaplen += addlen;
  755.     if (no_abbr_cnt && offset == 0)    /* and not used for abbreviations */
  756.     no_abbr_cnt += addlen;
  757.  
  758.     return OK;
  759. }
  760.  
  761. /*
  762.  * Return TRUE if there are no characters in the typeahead buffer that have
  763.  * not been typed (result from a mapping or come from ":normal").
  764.  */
  765.     int
  766. typebuf_typed()
  767. {
  768.     return typemaplen == 0;
  769. }
  770.  
  771. /*
  772.  * remove "len" characters from typebuf[typeoff + offset]
  773.  */
  774.     void
  775. del_typebuf(len, offset)
  776.     int    len;
  777.     int    offset;
  778. {
  779.     int        i;
  780.  
  781.     typelen -= len;
  782.     /*
  783.      * Easy case: Just increase typeoff.
  784.      */
  785.     if (offset == 0 && typebuflen - (typeoff + len) >= 3 * MAXMAPLEN + 3)
  786.     typeoff += len;
  787.     /*
  788.      * Have to move the characters in typebuf[] and noremapbuf[]
  789.      */
  790.     else
  791.     {
  792.     i = typeoff + offset;
  793.     /*
  794.      * Leave some extra room at the end to avoid reallocation.
  795.      */
  796.     if (typeoff > MAXMAPLEN)
  797.     {
  798.         vim_memmove(typebuf + MAXMAPLEN, typebuf + typeoff, (size_t)offset);
  799.         vim_memmove(noremapbuf + MAXMAPLEN, noremapbuf + typeoff,
  800.                                   (size_t)offset);
  801.         typeoff = MAXMAPLEN;
  802.     }
  803.     /* adjust typebuf (include the NUL at the end) */
  804.     vim_memmove(typebuf + typeoff + offset, typebuf + i + len,
  805.                           (size_t)(typelen - offset + 1));
  806.     /* adjust noremapbuf[] */
  807.     vim_memmove(noremapbuf + typeoff + offset, noremapbuf + i + len,
  808.                           (size_t)(typelen - offset));
  809.     }
  810.  
  811.     if (typemaplen > offset)        /* adjust typemaplen */
  812.     {
  813.     if (typemaplen < offset + len)
  814.         typemaplen = offset;
  815.     else
  816.         typemaplen -= len;
  817.     }
  818.     if (no_abbr_cnt > offset)        /* adjust no_abbr_cnt */
  819.     {
  820.     if (no_abbr_cnt < offset + len)
  821.         no_abbr_cnt = offset;
  822.     else
  823.         no_abbr_cnt -= len;
  824.     }
  825. }
  826.  
  827. /*
  828.  * Write typed characters to script file.
  829.  * If recording is on put the character in the recordbuffer.
  830.  */
  831.     static void
  832. gotchars(s, len)
  833.     char_u  *s;
  834.     int        len;
  835. {
  836.     int        c;
  837.     char_u  buf[2];
  838.  
  839.     /* remember how many chars were last recorded */
  840.     if (Recording)
  841.     last_recorded_len += len;
  842.  
  843.     buf[1] = NUL;
  844.     while (len--)
  845.     {
  846.     c = *s++;
  847.     updatescript(c);
  848.  
  849.     if (Recording)
  850.     {
  851.         buf[0] = c;
  852.         add_buff(&recordbuff, buf);
  853.     }
  854.     }
  855.     may_sync_undo();
  856. }
  857.  
  858. /*
  859.  * Sync undo.  Called when typed characters are obtained from the typeahead
  860.  * buffer, or when a menu is used.
  861.  * Do not sync:
  862.  * - In Insert mode, unless cursor key has been used.
  863.  * - While reading a script file.
  864.  * - When no_u_sync is non-zero.
  865.  */
  866.     static void
  867. may_sync_undo()
  868. {
  869.     if ((!(State & (INSERT + CMDLINE)) || arrow_used) &&
  870.                     scriptin[curscript] == NULL && !no_u_sync)
  871.     u_sync();
  872. }
  873.  
  874. /*
  875.  * When doing ":so! file", the current typeahead needs to be saved, and
  876.  * restored when "file" has been read completely.
  877.  */
  878. static char_u    *(sv_typebuf[NSCRIPT]);
  879. static char_u    *(sv_noremapbuf[NSCRIPT]);
  880. static int    sv_typebuflen[NSCRIPT];
  881. static int    sv_typeoff[NSCRIPT];
  882. static int    sv_typelen[NSCRIPT];
  883. static int    sv_typemaplen[NSCRIPT];
  884. static int    sv_no_abbr_cnt[NSCRIPT];
  885.  
  886.     int
  887. save_typebuf()
  888. {
  889.     init_typebuf();
  890.     sv_typebuf[curscript] = typebuf;
  891.     sv_noremapbuf[curscript] = noremapbuf;
  892.     sv_typebuflen[curscript] = typebuflen;
  893.     sv_typeoff[curscript] = typeoff;
  894.     sv_typelen[curscript] = typelen;
  895.     sv_typemaplen[curscript] = typemaplen;
  896.     sv_no_abbr_cnt[curscript] = no_abbr_cnt;
  897.     typebuf = alloc(TYPELEN_INIT);
  898.     noremapbuf = alloc(TYPELEN_INIT);
  899.     typebuflen = TYPELEN_INIT;
  900.     typeoff = 0;
  901.     typelen = 0;
  902.     typemaplen = 0;
  903.     no_abbr_cnt = 0;
  904.  
  905.     /* If out of memory: restore typebuf and close file. */
  906.     if (typebuf == NULL || noremapbuf == NULL)
  907.     {
  908.     closescript();
  909.     return FAIL;
  910.     }
  911.  
  912.     return OK;
  913. }
  914.  
  915. /*
  916.  * open new script file for ":so!" command
  917.  * return OK on success, FAIL on error
  918.  */
  919.     int
  920. openscript(name)
  921.     char_u *name;
  922. {
  923.     int oldcurscript;
  924.  
  925.     if (curscript + 1 == NSCRIPT)
  926.     {
  927.     emsg(e_nesting);
  928.     return FAIL;
  929.     }
  930.  
  931.     if (scriptin[curscript] != NULL)    /* already reading script */
  932.     ++curscript;
  933.                 /* use NameBuff for expanded name */
  934.     expand_env(name, NameBuff, MAXPATHL);
  935.     if ((scriptin[curscript] = fopen((char *)NameBuff, READBIN)) == NULL)
  936.     {
  937.     emsg2(e_notopen, name);
  938.     if (curscript)
  939.         --curscript;
  940.     return FAIL;
  941.     }
  942.     if (save_typebuf() == FAIL)
  943.     return FAIL;
  944.  
  945.     /*
  946.      * With command ":g/pat/so! file" we have to execute the
  947.      * commands from the file now.
  948.      */
  949.     if (global_busy)
  950.     {
  951.     OPARG    oa;
  952.  
  953.     clear_oparg(&oa);
  954.     State = NORMAL;
  955.     oldcurscript = curscript;
  956.     do
  957.     {
  958.         adjust_cursor();    /* put cursor on an existing line */
  959.         normal_cmd(&oa, FALSE);
  960.         vpeekc();        /* check for end of file */
  961.     }
  962.     while (scriptin[oldcurscript] != NULL);
  963.     State = CMDLINE;
  964.     }
  965.  
  966.     return OK;
  967. }
  968.  
  969. /*
  970.  * Close the currently active input script.
  971.  */
  972.     static void
  973. closescript()
  974. {
  975.     vim_free(typebuf);
  976.     vim_free(noremapbuf);
  977.     typebuf = sv_typebuf[curscript];
  978.     noremapbuf = sv_noremapbuf[curscript];
  979.     typebuflen = sv_typebuflen[curscript];
  980.     typelen = sv_typelen[curscript];
  981.     typeoff = sv_typeoff[curscript];
  982.     typemaplen = sv_typemaplen[curscript];
  983.     no_abbr_cnt = sv_no_abbr_cnt[curscript];
  984.  
  985.     fclose(scriptin[curscript]);
  986.     scriptin[curscript] = NULL;
  987.     if (curscript)
  988.     --curscript;
  989. }
  990.  
  991. /*
  992.  * updatescipt() is called when a character can be written into the script file
  993.  * or when we have waited some time for a character (c == 0)
  994.  *
  995.  * All the changed memfiles are synced if c == 0 or when the number of typed
  996.  * characters reaches 'updatecount' and 'updatecount' is non-zero.
  997.  */
  998.     void
  999. updatescript(c)
  1000.     int c;
  1001. {
  1002.     static int        count = 0;
  1003.  
  1004.     if (c && scriptout)
  1005.     putc(c, scriptout);
  1006.     if (c == 0 || (p_uc > 0 && ++count >= p_uc))
  1007.     {
  1008.     ml_sync_all(c == 0, TRUE);
  1009.     count = 0;
  1010.     }
  1011. }
  1012.  
  1013. #define K_NEEDMORET -1        /* keylen value for incomplete key-code */
  1014. #define M_NEEDMORET -2        /* keylen value for incomplete mapping */
  1015.  
  1016. static int old_char = -1;    /* ungotten character */
  1017.  
  1018.     int
  1019. vgetc()
  1020. {
  1021.     int        c, c2;
  1022.  
  1023.     mod_mask = 0x0;
  1024.     last_recorded_len = 0;
  1025.     for (;;)            /* this is done twice if there are modifiers */
  1026.     {
  1027.     if (mod_mask)        /* no mapping after modifier has been read */
  1028.     {
  1029.         ++no_mapping;
  1030.         ++allow_keys;
  1031.     }
  1032.     c = vgetorpeek(TRUE);
  1033.     if (mod_mask)
  1034.     {
  1035.         --no_mapping;
  1036.         --allow_keys;
  1037.     }
  1038.  
  1039.     /* Get two extra bytes for special keys */
  1040.     if (c == K_SPECIAL)
  1041.     {
  1042.         ++no_mapping;
  1043.         c2 = vgetorpeek(TRUE);    /* no mapping for these chars */
  1044.         c = vgetorpeek(TRUE);
  1045.         --no_mapping;
  1046.         if (c2 == KS_MODIFIER)
  1047.         {
  1048.         mod_mask = c;
  1049.         continue;
  1050.         }
  1051.         c = TO_SPECIAL(c2, c);
  1052.     }
  1053. #ifdef MSDOS
  1054.     /*
  1055.      * If K_NUL was typed, it is replaced by K_NUL, 3 in mch_inchar().
  1056.      * Delete the 3 here.
  1057.      */
  1058.     else if (c == K_NUL && vpeekc() == 3)
  1059.         (void)vgetorpeek(TRUE);
  1060. #endif
  1061.  
  1062.     return c;
  1063.     }
  1064. }
  1065.  
  1066.     int
  1067. vpeekc()
  1068. {
  1069.     return (vgetorpeek(FALSE));
  1070. }
  1071.  
  1072. /*
  1073.  * Call vpeekc() without causing anything to be mapped.
  1074.  * Return TRUE if a character is available, FALSE otherwise.
  1075.  */
  1076.     int
  1077. char_avail()
  1078. {
  1079.     int        retval;
  1080.  
  1081.     ++no_mapping;
  1082.     retval = vgetorpeek(FALSE);
  1083.     --no_mapping;
  1084.     return (retval != NUL);
  1085. }
  1086.  
  1087.     void
  1088. vungetc(c)    /* unget one character (can only be done once!) */
  1089.     int        c;
  1090. {
  1091.     old_char = c;
  1092. }
  1093.  
  1094. /*
  1095.  * get a character: 1. from a previously ungotten character
  1096.  *            2. from the stuffbuffer
  1097.  *            3. from the typeahead buffer
  1098.  *            4. from the user
  1099.  *
  1100.  * if "advance" is TRUE (vgetc()):
  1101.  *    really get the character.
  1102.  *    KeyTyped is set to TRUE in the case the user typed the key.
  1103.  *    KeyStuffed is TRUE if the character comes from the stuff buffer.
  1104.  * if "advance" is FALSE (vpeekc()):
  1105.  *    just look whether there is a character available.
  1106.  */
  1107.  
  1108.     static int
  1109. vgetorpeek(advance)
  1110.     int        advance;
  1111. {
  1112.     int            c, c1;
  1113.     int            keylen = 0;            /* init for gcc */
  1114.     char_u        *s;
  1115.     struct mapblock *mp;
  1116.     int            timedout = FALSE;        /* waited for more than 1 second
  1117.                         for mapping to complete */
  1118.     int            mapdepth = 0;        /* check for recursive mapping */
  1119.     int            mode_deleted = FALSE;   /* set when mode has been deleted */
  1120.     int            local_State;
  1121.     int            mlen;
  1122.     int            max_mlen;
  1123. #ifdef SHOWCMD
  1124.     int            i;
  1125.     int            new_wcol, new_wrow;
  1126. #endif
  1127. #ifdef USE_GUI
  1128.     int            idx;
  1129.     int            shape_changed = FALSE;  /* adjusted cursor shape */
  1130. #endif
  1131.     int            n;
  1132. #ifdef HAVE_LANGMAP
  1133.     int            c2;
  1134. #endif
  1135.     int            old_wcol, old_wrow;
  1136.  
  1137.     /*
  1138.      * This function doesn't work very well when called recursively.  This may
  1139.      * happen though, because of:
  1140.      * 1. The call to add_to_showcmd().    char_avail() is then used to check if
  1141.      * there is a character available, which calls this function.  In that
  1142.      * case we must return NUL, to indicate no character is available.
  1143.      * 2. A GUI callback function writes to the screen, causing a
  1144.      * wait_return().
  1145.      */
  1146.     if (vgetc_busy)
  1147.     return NUL;
  1148.  
  1149.     local_State = get_real_state();
  1150.  
  1151. /*
  1152.  * get a character: 1. from a previously ungotten character
  1153.  */
  1154.     if (old_char >= 0)
  1155.     {
  1156.     c = old_char;
  1157.     if (advance)
  1158.         old_char = -1;
  1159.     return c;
  1160.     }
  1161.  
  1162.     vgetc_busy = TRUE;
  1163.  
  1164.     if (advance)
  1165.     KeyStuffed = FALSE;
  1166.  
  1167.     init_typebuf();
  1168.     start_stuff();
  1169.     if (advance && typemaplen == 0)
  1170.     Exec_reg = FALSE;
  1171.     do
  1172.     {
  1173. /*
  1174.  * get a character: 2. from the stuffbuffer
  1175.  */
  1176.     c = read_stuff(advance);
  1177.     if (c != NUL && !got_int)
  1178.     {
  1179.         if (advance)
  1180.         {
  1181.         KeyTyped = FALSE;
  1182.         KeyStuffed = TRUE;
  1183.         }
  1184.         if (no_abbr_cnt == 0)
  1185.         no_abbr_cnt = 1;    /* no abbreviations now */
  1186.     }
  1187.     else
  1188.     {
  1189.         /*
  1190.          * Loop until we either find a matching mapped key, or we
  1191.          * are sure that it is not a mapped key.
  1192.          * If a mapped key sequence is found we go back to the start to
  1193.          * try re-mapping.
  1194.          */
  1195.         for (;;)
  1196.         {
  1197.         /*
  1198.          * ui_breakcheck() is slow, don't use it too often when
  1199.          * inside a mapping.  But call it each time for typed
  1200.          * characters.
  1201.          */
  1202.         if (typemaplen)
  1203.             line_breakcheck();
  1204.         else
  1205.             ui_breakcheck();        /* check for CTRL-C */
  1206.         if (got_int)
  1207.         {
  1208.             /* flush all input */
  1209.             c = inchar(typebuf, typebuflen - 1, 0L);
  1210.             /*
  1211.              * If inchar returns TRUE (script file was active) or we
  1212.              * are inside a mapping, get out of insert mode.
  1213.              * Otherwise we behave like having gotten a CTRL-C.
  1214.              * As a result typing CTRL-C in insert mode will
  1215.              * really insert a CTRL-C.
  1216.              */
  1217.             if ((c || typemaplen) && (State & (INSERT + CMDLINE)))
  1218.             c = ESC;
  1219.             else
  1220.             c = Ctrl('C');
  1221.             flush_buffers(TRUE);    /* flush all typeahead */
  1222.             break;
  1223.         }
  1224.         else if (typelen > 0)    /* check for a mappable key sequence */
  1225.         {
  1226.             /*
  1227.              * walk through one maphash[] list until we find an
  1228.              * entry that matches.
  1229.              *
  1230.              * Don't look for mappings if:
  1231.              * - timed out
  1232.              * - no_mapping set: mapping disabled (e.g. for CTRL-V)
  1233.              * - maphash_valid not set: no mappings present.
  1234.              * - typebuf[typeoff] should not be remapped
  1235.              * - in insert or cmdline mode and 'paste' option set
  1236.              * - waiting for "hit return to continue" and CR or SPACE
  1237.              *     typed
  1238.              * - waiting for a char with --more--
  1239.              * - in Ctrl-X mode, and we get a valid char for that mode
  1240.              */
  1241.             mp = NULL;
  1242.             max_mlen = 0;
  1243.             if (!timedout && no_mapping == 0 && maphash_valid
  1244.                 && (typemaplen == 0 ||
  1245.                     (p_remap && noremapbuf[typeoff] == FALSE))
  1246.                 && !(p_paste && (State & (INSERT + CMDLINE)))
  1247.                 && !(State == HITRETURN && (typebuf[typeoff] == CR
  1248.                           || typebuf[typeoff] == ' '))
  1249.                 && State != ASKMORE
  1250. #ifdef INSERT_EXPAND
  1251.                 && !(ctrl_x_mode
  1252.                        && vim_is_ctrl_x_key(typebuf[typeoff]))
  1253. #endif
  1254.                 )
  1255.             {
  1256.             c1 = typebuf[typeoff];
  1257. #ifdef HAVE_LANGMAP
  1258.             LANGMAP_ADJUST(c1, TRUE);
  1259. #endif
  1260.             for (mp = maphash[MAP_HASH(local_State, c1)];
  1261.                           mp != NULL; mp = mp->m_next)
  1262.             {
  1263.                 /*
  1264.                  * Only consider an entry if the first character
  1265.                  * matches and it is for the current state.
  1266.                  */
  1267.                 if (mp->m_keys[0] == c1 &&
  1268.                            (mp->m_mode & local_State))
  1269.                 {
  1270.                 /* find the match length of this mapping */
  1271.                 for (mlen = 1; mlen < typelen; ++mlen)
  1272.                 {
  1273. #ifdef HAVE_LANGMAP
  1274.                     c2 = typebuf[typeoff + mlen];
  1275.                     LANGMAP_ADJUST(c2, TRUE);
  1276.                     if (mp->m_keys[mlen] != c2)
  1277. #else
  1278.                     if (mp->m_keys[mlen] !=
  1279.                             typebuf[typeoff + mlen])
  1280. #endif
  1281.                     break;
  1282.                 }
  1283.  
  1284.                 /*
  1285.                  * Check an entry whether it matches.
  1286.                  * - Full match: mlen == keylen
  1287.                  * - Partly match: mlen == typelen
  1288.                  */
  1289.                 keylen = mp->m_keylen;
  1290.                 if (mlen == keylen ||
  1291.                     (mlen == typelen && typelen < keylen))
  1292.                 {
  1293.                     /*
  1294.                      * If one of the typed keys cannot be
  1295.                      * remapped, skip the entry.
  1296.                      */
  1297.                     s = noremapbuf + typeoff;
  1298.                     for (n = mlen; --n >= 0; )
  1299.                     if (*s++)
  1300.                         break;
  1301.                     if (n >= 0)
  1302.                     continue;
  1303.  
  1304.                     /*
  1305.                      * Need more chars for partly match.
  1306.                      */
  1307.                     if (keylen > typelen)
  1308.                     keylen = M_NEEDMORET;
  1309.                     break;
  1310.                 }
  1311.  
  1312.                 /*
  1313.                  * no match, may have to check for termcode at
  1314.                  * next character
  1315.                  */
  1316.                 if (max_mlen < mlen)
  1317.                     max_mlen = mlen;
  1318.                 }
  1319.             }
  1320.             }
  1321.             if (mp == NULL)        /* no matching mapping found */
  1322.             {
  1323.             /*
  1324.              * Check if we have a terminal code, when:
  1325.              *  mapping is allowed,
  1326.              *  keys have not been mapped,
  1327.              *  and not an ESC sequence, not in insert mode or
  1328.              *    p_ek is on,
  1329.              *  and when not timed out,
  1330.              */
  1331.             if ((no_mapping == 0 || allow_keys != 0) &&
  1332.                 (typemaplen == 0 ||
  1333.                      (p_remap && !noremapbuf[typeoff])) &&
  1334.                 !timedout)
  1335.             {
  1336.                 keylen = check_termcode(max_mlen + 1);
  1337.  
  1338.                 /*
  1339.                  * When getting a partial match, but the last
  1340.                  * characters were not typed, don't wait for a
  1341.                  * typed character to complete the termcode.
  1342.                  * This helps a lot when a ":normal" command ends
  1343.                  * in an ESC.
  1344.                  */
  1345.                 if (keylen < 0 && typelen == typemaplen)
  1346.                 keylen = 0;
  1347.             }
  1348.             else
  1349.                 keylen = 0;
  1350.             if (keylen == 0)    /* no matching terminal code */
  1351.             {
  1352. #ifdef AMIGA            /* check for window bounds report */
  1353.                 if (typemaplen == 0 &&
  1354.                         (typebuf[typeoff] & 0xff) == CSI)
  1355.                 {
  1356.                 for (s = typebuf + typeoff + 1;
  1357.                     s < typebuf + typeoff + typelen &&
  1358.                     (isdigit(*s) || *s == ';' || *s == ' ');
  1359.                     ++s)
  1360.                     ;
  1361.                 if (*s == 'r' || *s == '|') /* found one */
  1362.                 {
  1363.                     del_typebuf((int)(s + 1 -
  1364.                                (typebuf + typeoff)), 0);
  1365.                     /* get size and redraw screen */
  1366.                     set_winsize(0, 0, FALSE);
  1367.                     continue;
  1368.                 }
  1369.                 if (*s == NUL)        /* need more characters */
  1370.                     keylen = K_NEEDMORET;
  1371.                 }
  1372.                 if (keylen >= 0)
  1373. #endif
  1374.                 {
  1375. /*
  1376.  * get a character: 3. from the typeahead buffer
  1377.  */
  1378.                 c = typebuf[typeoff] & 255;
  1379.                 if (advance)    /* remove chars from typebuf */
  1380.                 {
  1381.                     if (typemaplen)
  1382.                     KeyTyped = FALSE;
  1383.                     else
  1384.                     {
  1385.                     KeyTyped = TRUE;
  1386.                     ++maptick;
  1387.                     /* write char to script file(s) */
  1388.                     gotchars(typebuf + typeoff, 1);
  1389.                     }
  1390.                     del_typebuf(1, 0);
  1391.                 }
  1392.                 break;        /* got character, break for loop */
  1393.                 }
  1394.             }
  1395.             if (keylen > 0)        /* full matching terminal code */
  1396.             {
  1397. #ifdef USE_GUI
  1398.                 if (typebuf[typeoff] == K_SPECIAL &&
  1399.                           typebuf[typeoff + 1] == KS_MENU)
  1400.                 {
  1401.                 /*
  1402.                  * Using a menu may cause a break in undo!
  1403.                  * It's like using gotchars(), but without
  1404.                  * recording or writing to a script file.
  1405.                  */
  1406.                 may_sync_undo();
  1407.                 del_typebuf(3, 0);
  1408.                 idx = gui_get_menu_index(current_menu,
  1409.                                  local_State);
  1410.                 if (idx != MENU_INDEX_INVALID)
  1411.                 {
  1412.                     ins_typebuf(current_menu->strings[idx],
  1413.                     current_menu->noremap[idx] ? -1 : 0,
  1414.                     0, TRUE);
  1415.                 }
  1416.                 }
  1417. #endif /* USE_GUI */
  1418.                 continue;    /* try mapping again */
  1419.             }
  1420.  
  1421.             /* partial match: get some more characters */
  1422.             keylen = K_NEEDMORET;
  1423.             }
  1424.             /* complete match */
  1425.             if (keylen >= 0 && keylen <= typelen)
  1426.             {
  1427.             /* write chars to script file(s) */
  1428.             if (keylen > typemaplen)
  1429.                 gotchars(typebuf + typeoff + typemaplen,
  1430.                             keylen - typemaplen);
  1431.  
  1432.             del_typebuf(keylen, 0);    /* remove the mapped keys */
  1433.  
  1434.             /*
  1435.              * Put the replacement string in front of mapstr.
  1436.              * The depth check catches ":map x y" and ":map y x".
  1437.              */
  1438.             if (++mapdepth >= p_mmd)
  1439.             {
  1440.                 EMSG("recursive mapping");
  1441.                 if (State == CMDLINE)
  1442.                 redrawcmdline();
  1443.                 else
  1444.                 setcursor();
  1445.                 flush_buffers(FALSE);
  1446.                 mapdepth = 0;    /* for next one */
  1447.                 c = -1;
  1448.                 break;
  1449.             }
  1450.             /*
  1451.              * Insert the 'to' part in the typebuf.
  1452.              * If 'from' field is the same as the start of the
  1453.              * 'to' field, don't remap the first character.
  1454.              * If m_noremap is set, don't remap the whole 'to'
  1455.              * part.
  1456.              */
  1457.             if (ins_typebuf(mp->m_str,
  1458.                 mp->m_noremap ? -1
  1459.                           : STRNCMP(mp->m_str, mp->m_keys,
  1460.                               (size_t)keylen) ? 0 : 1,
  1461.                 0, TRUE) == FAIL)
  1462.             {
  1463.                 c = -1;
  1464.                 break;
  1465.             }
  1466.             continue;
  1467.             }
  1468.         }
  1469.  
  1470.         /*
  1471.          * special case: if we get an <ESC> in insert mode and there
  1472.          * are no more characters at once, we pretend to go out of
  1473.          * insert mode.  This prevents the one second delay after
  1474.          * typing an <ESC>.  If we get something after all, we may
  1475.          * have to redisplay the mode. That the cursor is in the wrong
  1476.          * place does not matter.
  1477.          */
  1478.         c = 0;
  1479. #ifdef SHOWCMD
  1480.         new_wcol = curwin->w_wcol;
  1481.         new_wrow = curwin->w_wrow;
  1482. #endif
  1483.         if (       advance
  1484.             && typelen == 1
  1485.             && typebuf[typeoff] == ESC
  1486.             && !no_mapping
  1487.             && typemaplen == 0
  1488.             && (State & INSERT)
  1489.             && (p_timeout || (keylen == K_NEEDMORET && p_ttimeout))
  1490.             && (c = inchar(typebuf + typeoff + typelen, 3, 25L))
  1491.                                      == 0)
  1492.         {
  1493.             colnr_t    col, vcol;
  1494.             char_u    *ptr;
  1495.  
  1496.             if (p_smd)
  1497.             {
  1498.             unshowmode(TRUE);
  1499.             mode_deleted = TRUE;
  1500.             }
  1501. #ifdef USE_GUI
  1502.             /* may show different cursor shape */
  1503.             if (gui.in_use)
  1504.             {
  1505.             int        save_State;
  1506.  
  1507.             save_State = State;
  1508.             State = NORMAL;
  1509.             gui_update_cursor(TRUE, FALSE);
  1510.             State = save_State;
  1511.             shape_changed = TRUE;
  1512.             }
  1513. #endif
  1514.             validate_cursor();
  1515.             old_wcol = curwin->w_wcol;
  1516.             old_wrow = curwin->w_wrow;
  1517.  
  1518.             /* move cursor left, if possible */
  1519.             if (curwin->w_cursor.col != 0)
  1520.             {
  1521.             if (curwin->w_wcol)
  1522.             {
  1523.                 if (did_ai)
  1524.                 {
  1525.                 /*
  1526.                  * We are expecting to truncate the trailing
  1527.                  * white-space, so find the last non-white
  1528.                  * character -- webb
  1529.                  */
  1530.                 col = vcol = curwin->w_wcol = 0;
  1531.                 ptr = ml_get_curline();
  1532.                 while (col < curwin->w_cursor.col)
  1533.                 {
  1534.                     if (!vim_iswhite(ptr[col]))
  1535.                     curwin->w_wcol = vcol;
  1536.                     vcol += lbr_chartabsize(ptr + col,
  1537.                                    (colnr_t)vcol);
  1538.                     ++col;
  1539.                 }
  1540.                 if (curwin->w_p_nu)
  1541.                     curwin->w_wcol += 8;
  1542.                 }
  1543.                 else
  1544.                 --curwin->w_wcol;
  1545.             }
  1546.             else if (curwin->w_p_wrap && curwin->w_wrow)
  1547.             {
  1548.                 --curwin->w_wrow;
  1549.                 curwin->w_wcol = Columns - 1;
  1550.             }
  1551.             }
  1552.             setcursor();
  1553.             out_flush();
  1554. #ifdef SHOWCMD
  1555.             new_wcol = curwin->w_wcol;
  1556.             new_wrow = curwin->w_wrow;
  1557. #endif
  1558.             curwin->w_wcol = old_wcol;
  1559.             curwin->w_wrow = old_wrow;
  1560.         }
  1561.         if (c < 0)
  1562.             continue;    /* end of input script reached */
  1563.         typelen += c;
  1564.  
  1565.         /* buffer full, don't map */
  1566.         if (typelen >= typemaplen + MAXMAPLEN)
  1567.         {
  1568.             timedout = TRUE;
  1569.             continue;
  1570.         }
  1571. /*
  1572.  * get a character: 4. from the user
  1573.  */
  1574. #ifdef SHOWCMD
  1575.         /*
  1576.          * If we have a partial match (and are going to wait for more
  1577.          * input from the user), show the partially matched characters
  1578.          * to the user with showcmd -- webb.
  1579.          */
  1580.         i = 0;
  1581.         if (typelen > 0 && (State & (NORMAL | INSERT)) &&
  1582.                             advance && !exmode_active)
  1583.         {
  1584.             /* need to use the col and row from above here */
  1585.             old_wcol = curwin->w_wcol;
  1586.             old_wrow = curwin->w_wrow;
  1587.             curwin->w_wcol = new_wcol;
  1588.             curwin->w_wrow = new_wrow;
  1589.             push_showcmd();
  1590.             if (typelen > SHOWCMD_COLS)
  1591.             i = typelen - SHOWCMD_COLS;
  1592.             while (i < typelen)
  1593.             (void)add_to_showcmd(typebuf[typeoff + i++]);
  1594.             curwin->w_wcol = old_wcol;
  1595.             curwin->w_wrow = old_wrow;
  1596.         }
  1597. #endif
  1598.  
  1599.         c = inchar(typebuf + typeoff + typelen,
  1600.             typebuflen - typeoff - typelen - 1,
  1601.             !advance
  1602.                 ? 0
  1603.                 : ((typelen == 0 || !(p_timeout || (p_ttimeout &&
  1604.                     keylen == K_NEEDMORET)))
  1605.                     ? -1L
  1606.                     : ((keylen == K_NEEDMORET && p_ttm >= 0)
  1607.                         ? p_ttm
  1608.                         : p_tm)));
  1609.  
  1610. #ifdef SHOWCMD
  1611.         if (i)
  1612.             pop_showcmd();
  1613. #endif
  1614.  
  1615.         if (c < 0)
  1616.             continue;        /* end of input script reached */
  1617.         if (c == NUL)        /* no character available */
  1618.         {
  1619.             if (!advance)
  1620.             break;
  1621.             if (typelen)        /* timed out */
  1622.             {
  1623.             timedout = TRUE;
  1624.             continue;
  1625.             }
  1626.         }
  1627.         else
  1628.         {        /* allow mapping for just typed characters */
  1629.             while (typebuf[typeoff + typelen] != NUL)
  1630.             noremapbuf[typeoff + typelen++] = FALSE;
  1631.         }
  1632.         }        /* for (;;) */
  1633.     }    /* if (!character from stuffbuf) */
  1634.  
  1635.             /* if advance is FALSE don't loop on NULs */
  1636.     } while (c < 0 || (advance && c == NUL));
  1637.  
  1638.     /*
  1639.      * The "INSERT" message is taken care of here:
  1640.      *     if we return an ESC to exit insert mode, the message is deleted
  1641.      *     if we don't return an ESC but deleted the message before, redisplay it
  1642.      */
  1643.     if (advance && p_smd && (State & INSERT))
  1644.     {
  1645.     if (c == ESC && !mode_deleted && !no_mapping)
  1646.     {
  1647.         if (typelen && !KeyTyped)
  1648.         redraw_cmdline = TRUE;        /* delete mode later */
  1649.         else
  1650.         unshowmode(FALSE);
  1651.     }
  1652.     else if (c != ESC && mode_deleted)
  1653.     {
  1654.         if (typelen && !KeyTyped)
  1655.         redraw_cmdline = TRUE;        /* show mode later */
  1656.         else
  1657.         showmode();
  1658.     }
  1659.     }
  1660. #ifdef USE_GUI
  1661.     /* may unshow different cursor shape */
  1662.     if (gui.in_use && shape_changed)
  1663.     gui_update_cursor(TRUE, FALSE);
  1664. #endif
  1665.  
  1666.     vgetc_busy = FALSE;
  1667.  
  1668.     return c;
  1669. }
  1670.  
  1671. /*
  1672.  * inchar() - get one character from
  1673.  *    1. a scriptfile
  1674.  *    2. the keyboard
  1675.  *
  1676.  *  As much characters as we can get (upto 'maxlen') are put in buf and
  1677.  *  NUL terminated (buffer length must be 'maxlen' + 1).
  1678.  *  Minimum for 'maxlen' is 3!!!!
  1679.  *
  1680.  *  If we got an interrupt all input is read until none is available.
  1681.  *
  1682.  *  If wait_time == 0  there is no waiting for the char.
  1683.  *  If wait_time == n  we wait for n msec for a character to arrive.
  1684.  *  If wait_time == -1 we wait forever for a character to arrive.
  1685.  *
  1686.  *  Return the number of obtained characters.
  1687.  *  Return -1 when end of input script reached.
  1688.  */
  1689.  
  1690.     int
  1691. inchar(buf, maxlen, wait_time)
  1692.     char_u  *buf;
  1693.     int        maxlen;
  1694.     long    wait_time;            /* milli seconds */
  1695. {
  1696.     int        len = 0;        /* init for GCC */
  1697.     int        retesc = FALSE;        /* return ESC with gotint */
  1698.     int        c;
  1699.     int        i;
  1700.  
  1701.     if (wait_time == -1L || wait_time > 100L)  /* flush output before waiting */
  1702.     {
  1703.     cursor_on();
  1704.     out_flush();
  1705.     }
  1706.  
  1707.     /*
  1708.      * Don't reset these when at the hit-return prompt, otherwise a endless
  1709.      * recursive loop may result (write error in swapfile, hit-return, timeout
  1710.      * on char wait, flush swapfile, write error....).
  1711.      */
  1712.     if (State != HITRETURN)
  1713.     {
  1714.     did_outofmem_msg = FALSE;   /* display out of memory message (again) */
  1715.     did_swapwrite_msg = FALSE;  /* display swap file write error again */
  1716.     }
  1717.     undo_off = FALSE;            /* restart undo now */
  1718.  
  1719.     /*
  1720.      * first try script file
  1721.      *    If interrupted: Stop reading script files.
  1722.      */
  1723.     c = -1;
  1724.     while (scriptin[curscript] != NULL && c < 0)
  1725.     {
  1726.     if (got_int || (c = getc(scriptin[curscript])) < 0) /* reached EOF */
  1727.     {
  1728.         closescript();
  1729.         /*
  1730.          * When reading script file is interrupted, return an ESC to get
  1731.          * back to normal mode.
  1732.          * Otherwise return -1, because typebuf[] has changed.
  1733.          */
  1734.         if (got_int)
  1735.         retesc = TRUE;
  1736.         else
  1737.         return -1;
  1738.     }
  1739.     else
  1740.     {
  1741.         buf[0] = c;
  1742.         len = 1;
  1743.     }
  1744.     }
  1745.  
  1746.     if (c < 0)        /* did not get a character from script */
  1747.     {
  1748.     /*
  1749.      * If we got an interrupt, skip all previously typed characters and
  1750.      * return TRUE if quit reading script file.
  1751.      */
  1752.     if (got_int)
  1753.     {
  1754.         while (ui_inchar(buf, maxlen, 0L))
  1755.         ;
  1756.         return retesc;
  1757.     }
  1758.  
  1759.     /*
  1760.      * Always flush the output characters when getting input characters
  1761.      * from the user.
  1762.      */
  1763.     out_flush();
  1764.  
  1765.     /*
  1766.      * fill up to a third of the buffer, because each character may be
  1767.      * tripled below
  1768.      */
  1769.     len = ui_inchar(buf, maxlen / 3, wait_time);
  1770.     }
  1771.  
  1772.     /*
  1773.      * Two characters are special: NUL and K_SPECIAL.
  1774.      * Replace         NUL by K_SPECIAL KS_ZERO     K_FILLER
  1775.      * Replace K_SPECIAL by K_SPECIAL KS_SPECIAL K_FILLER
  1776.      * Don't replace K_SPECIAL when reading a script file.
  1777.      */
  1778.     for (i = len; --i >= 0; ++buf)
  1779.     {
  1780. #ifdef USE_GUI
  1781.     /* Any character can come after a CSI, don't escape it. */
  1782.     if (buf[0] == CSI && i >= 2)
  1783.     {
  1784.         buf += 2;
  1785.         i   -= 2;
  1786.         continue;
  1787.     }
  1788. #endif
  1789.     if (buf[0] == NUL || (buf[0] == K_SPECIAL && c < 0))
  1790.     {
  1791.         vim_memmove(buf + 3, buf + 1, (size_t)i);
  1792.         buf[2] = K_THIRD(buf[0]);
  1793.         buf[1] = K_SECOND(buf[0]);
  1794.         buf[0] = K_SPECIAL;
  1795.         buf += 2;
  1796.         len += 2;
  1797.     }
  1798.     }
  1799.     *buf = NUL;                    /* add trailing NUL */
  1800.     return len;
  1801. }
  1802.  
  1803. /*
  1804.  * map[!]            : show all key mappings
  1805.  * map[!] {lhs}            : show key mapping for {lhs}
  1806.  * map[!] {lhs} {rhs}        : set key mapping for {lhs} to {rhs}
  1807.  * noremap[!] {lhs} {rhs}   : same, but no remapping for {rhs}
  1808.  * unmap[!] {lhs}        : remove key mapping for {lhs}
  1809.  * abbr                : show all abbreviations
  1810.  * abbr {lhs}            : show abbreviations for {lhs}
  1811.  * abbr {lhs} {rhs}        : set abbreviation for {lhs} to {rhs}
  1812.  * noreabbr {lhs} {rhs}        : same, but no remapping for {rhs}
  1813.  * unabbr {lhs}            : remove abbreviation for {lhs}
  1814.  *
  1815.  * maptype == 1 for unmap command, 2 for noremap command.
  1816.  *
  1817.  * keys is pointer to any arguments. Note: keys cannot be a read-only string,
  1818.  * it will be modified.
  1819.  *
  1820.  * for :map   mode is NORMAL + VISUAL + OP_PENDING
  1821.  * for :map!  mode is INSERT + CMDLINE
  1822.  * for :cmap  mode is CMDLINE
  1823.  * for :imap  mode is INSERT
  1824.  * for :nmap  mode is NORMAL
  1825.  * for :vmap  mode is VISUAL
  1826.  * for :omap  mode is OP_PENDING
  1827.  *
  1828.  * for :abbr  mode is INSERT + CMDLINE
  1829.  * for :iabbr mode is INSERT
  1830.  * for :cabbr mode is CMDLINE
  1831.  *
  1832.  * Return 0 for success
  1833.  *      1 for invalid arguments
  1834.  *      2 for no match
  1835.  *      3 for ambiguety
  1836.  *      4 for out of mem
  1837.  */
  1838.     int
  1839. do_map(maptype, keys, mode, abbrev)
  1840.     int        maptype;
  1841.     char_u  *keys;
  1842.     int        mode;
  1843.     int        abbrev;        /* not a mapping but an abbreviation */
  1844. {
  1845.     struct mapblock    *mp, **mpp;
  1846.     char_u        *arg;
  1847.     char_u        *p;
  1848.     int            n;
  1849.     int            len = 0;    /* init for GCC */
  1850.     char_u        *newstr;
  1851.     int            hasarg;
  1852.     int            haskey;
  1853.     int            did_it = FALSE;
  1854.     int            round;
  1855.     char_u        *keys_buf = NULL;
  1856.     char_u        *arg_buf = NULL;
  1857.     int            retval = 0;
  1858.     int            do_backslash;
  1859.     int            hash;
  1860.     int            new_hash;
  1861.  
  1862.     validate_maphash();
  1863. /*
  1864.  * find end of keys and skip CTRL-Vs (and backslashes) in it
  1865.  * Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'.
  1866.  * with :unmap white space is included in the keys, no argument possible
  1867.  */
  1868.     p = keys;
  1869.     do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
  1870.     while (*p && (maptype == 1 || !vim_iswhite(*p)))
  1871.     {
  1872.     if ((p[0] == Ctrl('V') || (do_backslash && p[0] == '\\')) &&
  1873.                                   p[1] != NUL)
  1874.         ++p;        /* skip CTRL-V or backslash */
  1875.     ++p;
  1876.     }
  1877.     if (*p != NUL)
  1878.     *p++ = NUL;
  1879.     p = skipwhite(p);
  1880.     arg = p;
  1881.     hasarg = (*arg != NUL);
  1882.     haskey = (*keys != NUL);
  1883.  
  1884.     /* check for :unmap without argument */
  1885.     if (maptype == 1 && !haskey)
  1886.     {
  1887.     retval = 1;
  1888.     goto theend;
  1889.     }
  1890.  
  1891.     /*
  1892.      * If mapping has been given as ^V<C_UP> say, then replace the term codes
  1893.      * with the appropriate two bytes. If it is a shifted special key, unshift
  1894.      * it too, giving another two bytes.
  1895.      * replace_termcodes() may move the result to allocated memory, which
  1896.      * needs to be freed later (*keys_buf and *arg_buf).
  1897.      * replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
  1898.      */
  1899.     if (haskey)
  1900.     keys = replace_termcodes(keys, &keys_buf, TRUE);
  1901.     if (hasarg)
  1902.     arg = replace_termcodes(arg, &arg_buf, FALSE);
  1903.  
  1904. #ifdef FKMAP
  1905.     /*
  1906.      * when in right-to-left mode and alternate keymap option set,
  1907.      * reverse the character flow in the arg in Farsi.
  1908.      */
  1909.     if (p_altkeymap && curwin->w_p_rl)
  1910.     lrswap(arg);
  1911. #endif
  1912.  
  1913.     /*
  1914.      * check arguments and translate function keys
  1915.      */
  1916.     if (haskey)
  1917.     {
  1918.     len = STRLEN(keys);
  1919.     if (len > MAXMAPLEN)        /* maximum length of MAXMAPLEN chars */
  1920.     {
  1921.         retval = 1;
  1922.         goto theend;
  1923.     }
  1924.  
  1925.     if (abbrev && maptype != 1)
  1926.     {
  1927.         /*
  1928.          * If an abbreviation ends in a keyword character, the
  1929.          * rest must be all keyword-char or all non-keyword-char.
  1930.          * Otherwise we won't be able to find the start of it in a
  1931.          * vi-compatible way.
  1932.          * An abbrevation cannot contain white space.
  1933.          */
  1934.         if (vim_iswordc(keys[len - 1]))    /* ends in keyword char */
  1935.         for (n = 0; n < len - 2; ++n)
  1936.             if (vim_iswordc(keys[n]) != vim_iswordc(keys[len - 2]))
  1937.             {
  1938.             retval = 1;
  1939.             goto theend;
  1940.             }
  1941.         for (n = 0; n < len; ++n)
  1942.         if (vim_iswhite(keys[n]))
  1943.         {
  1944.             retval = 1;
  1945.             goto theend;
  1946.         }
  1947.     }
  1948.     }
  1949.  
  1950.     if (haskey && hasarg && abbrev)    /* if we will add an abbreviation */
  1951.     no_abbr = FALSE;        /* reset flag that indicates there are
  1952.                                 no abbreviations */
  1953.  
  1954.     if (!haskey || (maptype != 1 && !hasarg))
  1955.     msg_start();
  1956.  
  1957.     /*
  1958.      * Find an entry in the maphash[] list that matches.
  1959.      * For :unmap we may loop two times: once to try to unmap an entry with a
  1960.      * matching 'from' part, a second time, if the first fails, to unmap an
  1961.      * entry with a matching 'to' part. This was done to allow ":ab foo bar"
  1962.      * to be unmapped by typing ":unab foo", where "foo" will be replaced by
  1963.      * "bar" because of the abbreviation.
  1964.      */
  1965.     for (round = 0; (round == 0 || maptype == 1) && round <= 1 &&
  1966.                          !did_it && !got_int; ++round)
  1967.     {
  1968.     /* need to loop over all hash lists */
  1969.     for (hash = 0; hash < 256 && !got_int; ++hash)
  1970.     {
  1971.         if (abbrev)
  1972.         {
  1973.         if (hash)    /* there is only one abbreviation list */
  1974.             break;
  1975.         mpp = &first_abbr;
  1976.         }
  1977.         else
  1978.         mpp = &(maphash[hash]);
  1979.         for (mp = *mpp; mp != NULL && !got_int; mp = *mpp)
  1980.         {
  1981.  
  1982.         if (!(mp->m_mode & mode))   /* skip entries with wrong mode */
  1983.         {
  1984.             mpp = &(mp->m_next);
  1985.             continue;
  1986.         }
  1987.         if (!haskey)            /* show all entries */
  1988.         {
  1989.             showmap(mp);
  1990.             did_it = TRUE;
  1991.         }
  1992.         else                /* do we have a match? */
  1993.         {
  1994.             if (round)        /* second round: Try unmap "rhs" string */
  1995.             {
  1996.             n = STRLEN(mp->m_str);
  1997.             p = mp->m_str;
  1998.             }
  1999.             else
  2000.             {
  2001.             n = mp->m_keylen;
  2002.             p = mp->m_keys;
  2003.             }
  2004.             if (!STRNCMP(p, keys, (size_t)(n < len ? n : len)))
  2005.             {
  2006.             if (maptype == 1)    /* delete entry */
  2007.             {
  2008.                 if (n != len)    /* not a full match */
  2009.                 {
  2010.                 mpp = &(mp->m_next);
  2011.                 continue;
  2012.                 }
  2013.                 /*
  2014.                  * We reset the indicated mode bits. If nothing is
  2015.                  * left the entry is deleted below.
  2016.                  */
  2017.                 mp->m_mode &= ~mode;
  2018.                 did_it = TRUE;    /* remember we did something */
  2019.             }
  2020.             else if (!hasarg)    /* show matching entry */
  2021.             {
  2022.                 showmap(mp);
  2023.                 did_it = TRUE;
  2024.             }
  2025.             else if (n != len)    /* new entry is ambigious */
  2026.             {
  2027.                 if (abbrev)        /* for abbrev's that's ok */
  2028.                 {
  2029.                 mpp = &(mp->m_next);
  2030.                 continue;
  2031.                 }
  2032.                 retval = 3;
  2033.                 goto theend;
  2034.             }
  2035.             else            /* new rhs for existing entry */
  2036.             {
  2037.                 mp->m_mode &= ~mode;    /* remove mode bits */
  2038.                 if (mp->m_mode == 0 && !did_it) /* reuse entry */
  2039.                 {
  2040.                 newstr = vim_strsave(arg);
  2041.                 if (newstr == NULL)
  2042.                 {
  2043.                     retval = 4;        /* no mem */
  2044.                     goto theend;
  2045.                 }
  2046.                 vim_free(mp->m_str);
  2047.                 mp->m_str = newstr;
  2048.                 mp->m_noremap = maptype;
  2049.                 mp->m_mode = mode;
  2050.                 did_it = TRUE;
  2051.                 }
  2052.             }
  2053.             if (mp->m_mode == 0)    /* entry can be deleted */
  2054.             {
  2055.                 map_free(mpp);
  2056.                 continue;        /* continue with *mpp */
  2057.             }
  2058.  
  2059.             /*
  2060.              * May need to put this entry into another hash list.
  2061.              */
  2062.             new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
  2063.             if (!abbrev && new_hash != hash)
  2064.             {
  2065.                 *mpp = mp->m_next;
  2066.                 mp->m_next = maphash[new_hash];
  2067.                 maphash[new_hash] = mp;
  2068.  
  2069.                 continue;        /* continue with *mpp */
  2070.             }
  2071.             }
  2072.         }
  2073.         mpp = &(mp->m_next);
  2074.         }
  2075.     }
  2076.     }
  2077.  
  2078.     if (maptype == 1)                /* delete entry */
  2079.     {
  2080.     if (!did_it)
  2081.         retval = 2;                /* no match */
  2082.     goto theend;
  2083.     }
  2084.  
  2085.     if (!haskey || !hasarg)            /* print entries */
  2086.     {
  2087.     if (!did_it)
  2088.     {
  2089.         if (abbrev)
  2090.         MSG("No abbreviation found");
  2091.         else
  2092.         MSG("No mapping found");
  2093.     }
  2094.     goto theend;                /* listing finished */
  2095.     }
  2096.  
  2097.     if (did_it)            /* have added the new entry already */
  2098.     goto theend;
  2099. /*
  2100.  * Get here when we have to add a new entry to the maphash[] list or abbrlist.
  2101.  */
  2102.     mp = (struct mapblock *)alloc((unsigned)sizeof(struct mapblock));
  2103.     if (mp == NULL)
  2104.     {
  2105.     retval = 4;        /* no mem */
  2106.     goto theend;
  2107.     }
  2108.  
  2109.     mp->m_keys = vim_strsave(keys);
  2110.     mp->m_str = vim_strsave(arg);
  2111.     if (mp->m_keys == NULL || mp->m_str == NULL)
  2112.     {
  2113.     vim_free(mp->m_keys);
  2114.     vim_free(mp->m_str);
  2115.     vim_free(mp);
  2116.     retval = 4;    /* no mem */
  2117.     goto theend;
  2118.     }
  2119.     mp->m_keylen = STRLEN(mp->m_keys);
  2120.     mp->m_noremap = maptype;
  2121.     mp->m_mode = mode;
  2122.  
  2123.     /* add the new entry in front of the abbrlist or maphash[] list */
  2124.     if (abbrev)
  2125.     {
  2126.     mp->m_next = first_abbr;
  2127.     first_abbr = mp;
  2128.     }
  2129.     else
  2130.     {
  2131.     n = MAP_HASH(mp->m_mode, mp->m_keys[0]);
  2132.     mp->m_next = maphash[n];
  2133.     maphash[n] = mp;
  2134.     }
  2135.  
  2136. theend:
  2137.     vim_free(keys_buf);
  2138.     vim_free(arg_buf);
  2139.     return retval;
  2140. }
  2141.  
  2142. /*
  2143.  * Delete one entry from the abbrlist or maphash[].
  2144.  * "mpp" is a pointer to the m_next field of the PREVIOUS entry!
  2145.  */
  2146.     static void
  2147. map_free(mpp)
  2148.     struct mapblock    **mpp;
  2149. {
  2150.     struct mapblock    *mp;
  2151.  
  2152.     mp = *mpp;
  2153.     vim_free(mp->m_keys);
  2154.     vim_free(mp->m_str);
  2155.     *mpp = mp->m_next;
  2156.     vim_free(mp);
  2157. }
  2158.  
  2159. /*
  2160.  * Initialize maphash[] for first use.
  2161.  */
  2162.     static void
  2163. validate_maphash()
  2164. {
  2165.     if (!maphash_valid)
  2166.     {
  2167.     vim_memset(maphash, 0, sizeof(maphash));
  2168.     maphash_valid = TRUE;
  2169.     }
  2170. }
  2171.  
  2172. /*
  2173.  * Get the mapping mode from the command name.
  2174.  */
  2175.     int
  2176. get_map_mode(cmdp, forceit)
  2177.     char_u    **cmdp;
  2178.     int        forceit;
  2179. {
  2180.     char_u    *p;
  2181.     int        modec;
  2182.     int        mode;
  2183.  
  2184.     p = *cmdp;
  2185.     modec = *p++;
  2186.     if (modec == 'i')
  2187.     mode = INSERT;                /* :imap */
  2188.     else if (modec == 'c')
  2189.     mode = CMDLINE;                /* :cmap */
  2190.     else if (modec == 'n' && *p != 'o')            /* avoid :noremap */
  2191.     mode = NORMAL;                /* :nmap */
  2192.     else if (modec == 'v')
  2193.     mode = VISUAL;                /* :vmap */
  2194.     else if (modec == 'o')
  2195.     mode = OP_PENDING;            /* :omap */
  2196.     else
  2197.     {
  2198.     --p;
  2199.     if (forceit)
  2200.         mode = INSERT + CMDLINE;        /* :map ! */
  2201.     else
  2202.         mode = VISUAL + NORMAL + OP_PENDING;/* :map */
  2203.     }
  2204.  
  2205.     *cmdp = p;
  2206.     return mode;
  2207. }
  2208.  
  2209. /*
  2210.  * Clear all mappings or abbreviations.
  2211.  * 'abbr' should be FALSE for mappings, TRUE for abbreviations.
  2212.  */
  2213.     void
  2214. map_clear(cmdp, forceit, abbr)
  2215.     char_u  *cmdp;
  2216.     int        forceit;
  2217.     int        abbr;
  2218. {
  2219.     struct mapblock    *mp, **mpp;
  2220.     int        mode;
  2221.     int        hash;
  2222.     int        new_hash;
  2223.  
  2224.     validate_maphash();
  2225.  
  2226.     mode = get_map_mode(&cmdp, forceit);
  2227.  
  2228.     for (hash = 0; hash < 256; ++hash)
  2229.     {
  2230.     if (abbr)
  2231.     {
  2232.         if (hash)        /* there is only one abbrlist */
  2233.         break;
  2234.         mpp = &first_abbr;
  2235.     }
  2236.     else
  2237.         mpp = &maphash[hash];
  2238.     while (*mpp != NULL)
  2239.     {
  2240.         mp = *mpp;
  2241.         if (mp->m_mode & mode)
  2242.         {
  2243.         mp->m_mode &= ~mode;
  2244.         if (mp->m_mode == 0) /* entry can be deleted */
  2245.         {
  2246.             map_free(mpp);
  2247.             continue;
  2248.         }
  2249.         /*
  2250.          * May need to put this entry into another hash list.
  2251.          */
  2252.         new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
  2253.         if (!abbr && new_hash != hash)
  2254.         {
  2255.             *mpp = mp->m_next;
  2256.             mp->m_next = maphash[new_hash];
  2257.             maphash[new_hash] = mp;
  2258.             continue;        /* continue with *mpp */
  2259.         }
  2260.         }
  2261.         mpp = &(mp->m_next);
  2262.     }
  2263.     }
  2264. }
  2265.  
  2266.     static void
  2267. showmap(mp)
  2268.     struct mapblock *mp;
  2269. {
  2270.     int len = 1;
  2271.  
  2272.     if (msg_didout)
  2273.     msg_putchar('\n');
  2274.     if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
  2275.     msg_putchar('!');            /* :map! */
  2276.     else if (mp->m_mode & INSERT)
  2277.     msg_putchar('i');            /* :imap */
  2278.     else if (mp->m_mode & CMDLINE)
  2279.     msg_putchar('c');            /* :cmap */
  2280.     else if ((mp->m_mode & (NORMAL + VISUAL + OP_PENDING))
  2281.                           == NORMAL + VISUAL + OP_PENDING)
  2282.     msg_putchar(' ');            /* :map */
  2283.     else
  2284.     {
  2285.     len = 0;
  2286.     if (mp->m_mode & NORMAL)
  2287.     {
  2288.         msg_putchar('n');        /* :nmap */
  2289.         ++len;
  2290.     }
  2291.     if (mp->m_mode & OP_PENDING)
  2292.     {
  2293.         msg_putchar('o');        /* :omap */
  2294.         ++len;
  2295.     }
  2296.     if (mp->m_mode & VISUAL)
  2297.     {
  2298.         msg_putchar('v');        /* :vmap */
  2299.         ++len;
  2300.     }
  2301.     }
  2302.     while (++len <= 3)
  2303.     msg_putchar(' ');
  2304.  
  2305.     /* Get length of what we write */
  2306.     len = msg_outtrans_special(mp->m_keys, TRUE);
  2307.     do
  2308.     {
  2309.     msg_putchar(' ');        /* padd with blanks */
  2310.     ++len;
  2311.     } while (len < 12);
  2312.     if (mp->m_noremap)
  2313.     msg_putchar('*');
  2314.     else
  2315.     msg_putchar(' ');
  2316.     /* Use FALSE below if we only want things like <Up> to show up as such on
  2317.      * the rhs, and not M-x etc, TRUE gets both -- webb
  2318.      */
  2319.     msg_outtrans_special(mp->m_str, TRUE);
  2320.     out_flush();            /* show one line at a time */
  2321. }
  2322.  
  2323. /*
  2324.  * Check for an abbreviation.
  2325.  * Cursor is at ptr[col]. When inserting, mincol is where insert started.
  2326.  * "c" is the character typed before check_abbr was called.
  2327.  *
  2328.  * Historic vi practice: The last character of an abbreviation must be an id
  2329.  * character ([a-zA-Z0-9_]). The characters in front of it must be all id
  2330.  * characters or all non-id characters. This allows for abbr. "#i" to
  2331.  * "#include".
  2332.  *
  2333.  * Vim addition: Allow for abbreviations that end in a non-keyword character.
  2334.  * Then there must be white space before the abbr.
  2335.  *
  2336.  * return TRUE if there is an abbreviation, FALSE if not
  2337.  */
  2338.     int
  2339. check_abbr(c, ptr, col, mincol)
  2340.     int        c;
  2341.     char_u  *ptr;
  2342.     int        col;
  2343.     int        mincol;
  2344. {
  2345.     int            len;
  2346.     int            j;
  2347.     char_u        tb[4];
  2348.     struct mapblock *mp;
  2349.     int            is_id = TRUE;
  2350.     int            vim_abbr;
  2351.  
  2352.     if (no_abbr_cnt)        /* abbrev. are not recursive */
  2353.     return FALSE;
  2354.  
  2355.     /*
  2356.      * Check for word before the cursor: If it ends in a keyword char all
  2357.      * chars before it must be al keyword chars or non-keyword chars, but not
  2358.      * white space. If it ends in a non-keyword char we accept any characters
  2359.      * before it except white space.
  2360.      */
  2361.     if (col == 0)                /* cannot be an abbr. */
  2362.     return FALSE;
  2363.  
  2364.     if (!vim_iswordc(ptr[col - 1]))
  2365.     vim_abbr = TRUE;            /* Vim added abbr. */
  2366.     else
  2367.     {
  2368.     vim_abbr = FALSE;            /* vi compatible abbr. */
  2369.     if (col > 1)
  2370.         is_id = vim_iswordc(ptr[col - 2]);
  2371.     }
  2372.     for (len = col - 1; len > 0 && !vim_isspace(ptr[len - 1]) &&
  2373.                (vim_abbr || is_id == vim_iswordc(ptr[len - 1])); --len)
  2374.     ;
  2375.  
  2376.     if (len < mincol)
  2377.     len = mincol;
  2378.     if (len < col)        /* there is a word in front of the cursor */
  2379.     {
  2380.     ptr += len;
  2381.     len = col - len;
  2382.     for (mp = first_abbr; mp; mp = mp->m_next)
  2383.     {
  2384.         /* find entries with right mode and keys */
  2385.         if (       (mp->m_mode & State)
  2386.             && mp->m_keylen == len
  2387.             && !STRNCMP(mp->m_keys, ptr, (size_t)len))
  2388.         break;
  2389.     }
  2390.     if (mp)
  2391.     {
  2392.         /*
  2393.          * Found a match:
  2394.          * Insert the rest of the abbreviation in typebuf[].
  2395.          * This goes from end to start.
  2396.          *
  2397.          * Characters 0x000 - 0x100: normal chars, may need CTRL-V,
  2398.          * except K_SPECIAL: Becomes K_SPECIAL KS_SPECIAL K_FILLER
  2399.          * Characters where IS_SPECIAL() == TRUE: key codes, need
  2400.          * K_SPECIAL. Other characters (with ABBR_OFF): don't use CTRL-V.
  2401.          *
  2402.          * Character CTRL(']') is treated specially - it completes the
  2403.          * abbreviation, but is not inserted into the input stream.
  2404.          */
  2405.         j = 0;
  2406.                         /* special key code, split up */
  2407.         if (c != Ctrl(']'))
  2408.         {
  2409.         if (IS_SPECIAL(c) || c == K_SPECIAL)
  2410.         {
  2411.             tb[j++] = K_SPECIAL;
  2412.             tb[j++] = K_SECOND(c);
  2413.             c = K_THIRD(c);
  2414.         }
  2415.         else if (c < 0x100 && (c < ' ' || c > '~'))
  2416.             tb[j++] = Ctrl('V');    /* special char needs CTRL-V */
  2417.         tb[j++] = c;
  2418.         tb[j] = NUL;
  2419.                         /* insert the last typed char */
  2420.         (void)ins_typebuf(tb, TRUE, 0, TRUE);
  2421.         }
  2422.                         /* insert the to string */
  2423.         (void)ins_typebuf(mp->m_str, mp->m_noremap ? -1 : 0, 0, TRUE);
  2424.                         /* no abbrev. for these chars */
  2425.         no_abbr_cnt += STRLEN(mp->m_str) + j + 1;
  2426.  
  2427.         tb[0] = Ctrl('H');
  2428.         tb[1] = NUL;
  2429.         while (len--)            /* delete the from string */
  2430.         (void)ins_typebuf(tb, TRUE, 0, TRUE);
  2431.         return TRUE;
  2432.     }
  2433.     }
  2434.     return FALSE;
  2435. }
  2436.  
  2437. /*
  2438.  * Write map commands for the current mappings to an .exrc file.
  2439.  * Return FAIL on error, OK otherwise.
  2440.  */
  2441.     int
  2442. makemap(fd)
  2443.     FILE *fd;
  2444. {
  2445.     struct mapblock *mp;
  2446.     char_u        c1, c2;
  2447.     char_u        *p;
  2448.     int            abbr;
  2449.     int            hash;
  2450.  
  2451.     validate_maphash();
  2452.  
  2453.     /*
  2454.      * Do the loop twice: Once for mappings, once for abbreviations.
  2455.      * Then loop over all map hash lists.
  2456.      */
  2457.     for (abbr = 0; abbr < 2; ++abbr)
  2458.     for (hash = 0; hash < 256; ++hash)
  2459.     {
  2460.         if (abbr)
  2461.         {
  2462.         if (hash)        /* there is only one abbr list */
  2463.             break;
  2464.         mp = first_abbr;
  2465.         }
  2466.         else
  2467.         mp = maphash[hash];
  2468.         for ( ; mp; mp = mp->m_next)
  2469.         {
  2470.         c1 = NUL;
  2471.         c2 = NUL;
  2472.         if (abbr)
  2473.             p = (char_u *)"abbr";
  2474.         else
  2475.             p = (char_u *)"map";
  2476.         switch (mp->m_mode)
  2477.         {
  2478.             case NORMAL + VISUAL + OP_PENDING:
  2479.             break;
  2480.             case NORMAL:
  2481.             c1 = 'n';
  2482.             break;
  2483.             case VISUAL:
  2484.             c1 = 'v';
  2485.             break;
  2486.             case OP_PENDING:
  2487.             c1 = 'o';
  2488.             break;
  2489.             case NORMAL + VISUAL:
  2490.             c1 = 'n';
  2491.             c2 = 'v';
  2492.             break;
  2493.             case VISUAL + OP_PENDING:
  2494.             c1 = 'v';
  2495.             c2 = 'o';
  2496.             break;
  2497.             case NORMAL + OP_PENDING:
  2498.             c1 = 'n';
  2499.             c2 = 'o';
  2500.             break;
  2501.             case CMDLINE + INSERT:
  2502.             if (!abbr)
  2503.                 p = (char_u *)"map!";
  2504.             break;
  2505.             case CMDLINE:
  2506.             c1 = 'c';
  2507.             break;
  2508.             case INSERT:
  2509.             c1 = 'i';
  2510.             break;
  2511.             default:
  2512.             EMSG("makemap: Illegal mode");
  2513.             return FAIL;
  2514.         }
  2515.         do    /* may do this twice if c2 is set */
  2516.         {
  2517.             if (c1 && putc(c1, fd) < 0)
  2518.             return FAIL;
  2519.             if (mp->m_noremap && fprintf(fd, "nore") < 0)
  2520.             return FAIL;
  2521.             if (fprintf(fd, (char *)p) < 0)
  2522.             return FAIL;
  2523.  
  2524.             if (       putc(' ', fd) < 0
  2525.                 || putescstr(fd, mp->m_keys, FALSE) == FAIL
  2526.                 || putc(' ', fd) < 0
  2527.                 || putescstr(fd, mp->m_str, FALSE) == FAIL
  2528. #ifdef USE_CRNL
  2529.                 || putc('\r', fd) < 0
  2530. #endif
  2531.                 || putc('\n', fd) < 0)
  2532.             return FAIL;
  2533.             c1 = c2;
  2534.             c2 = NUL;
  2535.         }
  2536.         while (c1);
  2537.         }
  2538.     }
  2539.     return OK;
  2540. }
  2541.  
  2542. /*
  2543.  * write escape string to file
  2544.  *
  2545.  * return FAIL for failure, OK otherwise
  2546.  */
  2547.     int
  2548. putescstr(fd, str, set)
  2549.     FILE    *fd;
  2550.     char_u    *str;
  2551.     int        set;        /* TRUE for makeset, FALSE for makemap */
  2552. {
  2553.     int        c;
  2554.     int        modifiers;
  2555.  
  2556.     for ( ; *str; ++str)
  2557.     {
  2558.     c = *str;
  2559.     /*
  2560.      * Special key codes have to be translated to be able to make sense
  2561.      * when they are read back.
  2562.      */
  2563.     if (c == K_SPECIAL && !set)
  2564.     {
  2565.         modifiers = 0x0;
  2566.         if (str[1] == KS_MODIFIER)
  2567.         {
  2568.         modifiers = str[2];
  2569.         str += 3;
  2570.         c = *str;
  2571.         }
  2572.         if (c == K_SPECIAL)
  2573.         {
  2574.         c = TO_SPECIAL(str[1], str[2]);
  2575.         str += 2;
  2576.         }
  2577.         if (IS_SPECIAL(c) || modifiers)    /* special key */
  2578.         {
  2579.         fprintf(fd, (char *)get_special_key_name(c, modifiers));
  2580.         continue;
  2581.         }
  2582.     }
  2583.     /*
  2584.      * A '\n' in a map command should be written as <NL>.
  2585.      * A '\n' in a set command should be written as \^V^J.
  2586.      */
  2587.     if (c == NL)
  2588.     {
  2589.         if (set)
  2590.         fprintf(fd, "\\\026\n");
  2591.         else
  2592.         fprintf(fd, "<NL>");
  2593.         continue;
  2594.     }
  2595.     /*
  2596.      * some characters have to be escaped with CTRL-V to
  2597.      * prevent them from misinterpreted in DoOneCmd().
  2598.      * A space, Tab and '"' has to be escaped with a backslash to
  2599.      * prevent it to be misinterpreted in do_set().
  2600.      */
  2601.     if (set && (vim_iswhite(c) || c == '"' || c == '\\'))
  2602.     {
  2603.         if (putc('\\', fd) < 0)
  2604.         return FAIL;
  2605.     }
  2606.     else if (c < ' ' || c > '~' || c == '|')
  2607.     {
  2608.         if (putc(Ctrl('V'), fd) < 0)
  2609.         return FAIL;
  2610.     }
  2611.     if (putc(c, fd) < 0)
  2612.         return FAIL;
  2613.     }
  2614.     return OK;
  2615. }
  2616.  
  2617. /*
  2618.  * Check all mappings for the presence of special key codes.
  2619.  * Used after ":set term=xxx".
  2620.  */
  2621.     void
  2622. check_map_keycodes()
  2623. {
  2624.     struct mapblock *mp;
  2625.     char_u        *p;
  2626.     int            i;
  2627.     char_u        buf[3];
  2628.     char_u        *save_name;
  2629.     int            abbr;
  2630.     int            hash;
  2631.  
  2632.     validate_maphash();
  2633.     save_name = sourcing_name;
  2634.     sourcing_name = (char_u *)"mappings";/* don't give error messages */
  2635.  
  2636.     /*
  2637.      * Do the loop twice: Once for mappings, once for abbreviations.
  2638.      * Then loop over all map hash lists.
  2639.      */
  2640.     for (abbr = 0; abbr < 2; ++abbr)
  2641.     for (hash = 0; hash < 256; ++hash)
  2642.     {
  2643.         if (abbr)
  2644.         {
  2645.         if (hash)        /* there is only one abbr list */
  2646.             break;
  2647.         mp = first_abbr;
  2648.         }
  2649.         else
  2650.         mp = maphash[hash];
  2651.         for ( ; mp != NULL; mp = mp->m_next)
  2652.         {
  2653.         for (i = 0; i <= 1; ++i)    /* do this twice */
  2654.         {
  2655.             if (i == 0)
  2656.             p = mp->m_keys;        /* once for the "from" part */
  2657.             else
  2658.             p = mp->m_str;        /* and once for the "to" part */
  2659.             while (*p)
  2660.             {
  2661.             if (*p == K_SPECIAL)
  2662.             {
  2663.                 ++p;
  2664.                 if (*p < 128)   /* for "normal" termcap entries */
  2665.                 {
  2666.                 buf[0] = p[0];
  2667.                 buf[1] = p[1];
  2668.                 buf[2] = NUL;
  2669.                 (void)add_termcap_entry(buf, FALSE);
  2670.                 }
  2671.                 ++p;
  2672.             }
  2673.             ++p;
  2674.             }
  2675.         }
  2676.         }
  2677.     }
  2678.     sourcing_name = save_name;
  2679. }
  2680.